package com.poi.demopoi.controller;

import com.poi.demopoi.domain.EmployeeVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

public class Producer extends Thread {
    private static final Logger log = LoggerFactory.getLogger(Producer.class);


    //阻塞队列，防止多线程问题以及限制内存使用量
    private ArrayBlockingQueue<List<EmployeeVO>> queue;
    private Future<List<EmployeeVO>> futureResult;

    public Producer(ArrayBlockingQueue<List<EmployeeVO>> queue, Future<List<EmployeeVO>> futureResult, String threadName) {
        super(threadName);
        this.queue = queue;
        this.futureResult = futureResult;
    }

    @Override
    public void run() {
        Long startTime = System.currentTimeMillis();
        while (true) {
            try {
                if (futureResult.isCancelled()) {
                    break;
                }
                if (futureResult.isDone()) {
                    //如果队列已满，生产者休眠300ms
                    if (queue.remainingCapacity() < 1) {
                        log.info(String.format("生产者线程[%s]: 队列已满，休眠300ms", this.getName()));
                        Thread.sleep(300);
                        continue;
                    }
                    List<EmployeeVO> orderFinanceStatisticsDTOList = futureResult.get();

                    Long endTime = System.currentTimeMillis();
                    log.info(String.format("生产者线程[%s]成功获取1W条数据，耗时：[%s]ms", this.getName(), (endTime - startTime)));
                    //将数据放入阻塞队列
                    queue.put(orderFinanceStatisticsDTOList);
                    log.info(String.format("生产者线程[%s]成功入队1W条数据，在队列阻塞：[%s]ms", this.getName(), System.currentTimeMillis() - endTime));
                    break;
                } else {
                    log.info(String.format("生产者线程[%s]: 查询未结束，休眠300ms", this.getName()));
                    Thread.sleep(300);
                }
            } catch (InterruptedException | ExecutionException e) {
                log.error(String.format("生产者线程[%s]失败-->", this.getName()), e);
                break;
            }
        }
    }
}
